#pragma once

// 通用 buffer
#include <iostream>
#include <vector>
#include <assert.h>
#include <string.h>
#include <ctime>
#include <signal.h>

// 套接字
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>

// channel
#include <functional>
#include <sys/epoll.h>

// poll
#include <unordered_map>

// EventLoop
#include <vector>
#include <mutex>
#include <thread>
#include <memory>
#include <sys/eventfd.h>
#include <sys/timerfd.h>

// Connection
#include <typeinfo>

// LoopTherad
#include <condition_variable>

/*日志宏接口*/
#define INFO 0
#define DEBUG 1
#define ERROR 2
#define LOG_LEVEL ERROR
#define LOG(level, format, ...)                                                                                \
    do                                                                                                         \
    {                                                                                                          \
        if (level < LOG_LEVEL)                                                                                 \
            break;                                                                                             \
        time_t t = time(nullptr);                                                                              \
        struct tm *ltm = localtime(&t);                                                                        \
        char tmp[32] = {0};                                                                                    \
        strftime(tmp, 31, "%H:%M:%S", ltm);                                                                    \
        fprintf(stdout, "[%p %s %s:%d] " format "\n", pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)
#define INFO_LOG(format, ...) LOG(INFO, format, ##__VA_ARGS__)
#define DEBUG_LOG(format, ...) LOG(DEBUG, format, ##__VA_ARGS__)
#define ERROR_LOG(format, ...) LOG(ERROR, format, ##__VA_ARGS__)

#define BUFFER_DEAFAULT_SIZE 1024

class Buffer
{
private:
    std::vector<char> _buffer;
    uint64_t _reader_idx; /*当前读写相较起始地址的偏移量*/
    uint64_t _writer_idx;

public:
    Buffer() : _reader_idx(0), _writer_idx(0), _buffer(BUFFER_DEAFAULT_SIZE)
    {
    }
    char *Begin() { return &*_buffer.begin(); }
    char *GetWritePos() /*获取当前可写入位置*/
    {
        return Begin() + _writer_idx;
    }
    char *GetReadPos() /*获取当前可读取位置*/
    {
        return Begin() + _reader_idx;
    }
    uint64_t HeadIdeleSize() /*获取缓冲区前部分的空闲空间大小*/
    {
        return _reader_idx;
    }
    uint64_t TailIdeleSize() /*获取缓冲区后部分的空闲空间大小*/
    {
        return _buffer.size() - _writer_idx;
    }
    uint64_t WriteableSize() /*获取可写数据大小【移动 + 扩容】*/
    {
        return HeadIdeleSize() + TailIdeleSize();
    }
    uint64_t ReadableSize() /*获取可读数据大小【可读大小 = 可写位置 - 可读位置】*/
    {
        return _writer_idx - _reader_idx;
    }
    void EnsureWriteSpace(uint64_t len) /*确保可写空间足够*/
    {
        if (TailIdeleSize() >= len) // 空间足够，直接写
            return;
        // 末尾空间不足，先判断前部分和后部分加起来是否足够
        if (HeadIdeleSize() + TailIdeleSize() >= len)
        {
            // 将可写字段整个移动到缓冲区起始位置，更新完毕读写位置，再写入
            uint64_t rdsize = ReadableSize();                        // 1. 因为写位置之前可能还有数据没有被读取
            std::copy(GetReadPos(), GetReadPos() + rdsize, Begin()); // 2. 将这段需要读的数据先放在起始位置。
            _reader_idx = 0;
            _writer_idx = rdsize;
        }
        else
        {
            // 说明加起来也不够，直接从可写位置处扩容
            _buffer.resize(_writer_idx + len);
        }
    }

    void Write(const void *data, uint64_t len) /*写入数据*/
    {
        // 1.保证有足够空间
        if (len == 0)
            return;
        EnsureWriteSpace(len);
        const char *d = (const char *)data;
        std::copy(d, d + len, GetWritePos());
    }
    void WriteAndPush(const void *data, uint64_t len)
    {
        Write(data, len);
        MoveWriteOffset(len);
    }
    void WriteString(const std::string &data)
    {
        return Write(data.c_str(), data.size());
    }
    void WriteStringAndPush(const std::string &data)
    {
        WriteString(data);
        MoveWriteOffset(data.size());
    }
    void WriteBuffer(Buffer &data)
    {
        return Write(data.GetReadPos(), data.ReadableSize());
    }
    void WriteBuffeAndPush(Buffer &data)
    {
        WriteBuffer(data);
        MoveWriteOffset(data.ReadableSize());
    }
    void Read(void *buf, uint64_t len) /*读取数据*/
    {
        assert(len <= ReadableSize());
        std::copy(GetReadPos(), GetReadPos() + len, (char *)buf);
    }
    void ReadAndPop(void *buf, uint64_t len)
    {
        Read(buf, len);
        MoveReadOffset(len);
    }
    std::string ReadAsString(uint64_t len)
    {
        assert(len <= ReadableSize());
        std::string str;
        str.resize(len);
        Read(&str[0], len);
        return str;
    }
    std::string ReadAsStringAndPop(uint64_t len)
    {
        std::string str = ReadAsString(len);
        MoveReadOffset(len);
        return str;
    }

    void MoveReadOffset(uint64_t len) /*读取位置的移动接口*/
    {
        if (len == 0)
            return;
        assert(len <= ReadableSize()); // 向后移动大小必须小于等于可读大小
        _reader_idx += len;
    }
    void MoveWriteOffset(uint64_t len) /*写入位置的移动接口*/
    {
        assert(len <= TailIdeleSize()); // 写位置向后移动的大小必须小于等于后面的剩余空间，不能加上前部分的空间
        _writer_idx += len;
    }
    char *FindCRLF() /*寻找换行字符*/
    {
        void *ret = memchr(GetReadPos(), '\n', ReadableSize());
        return (char *)ret;
    }
    std::string GetLine() /* 获取一行字符 */
    {
        char *pos = FindCRLF();
        if (pos == nullptr)
            return "";
        return ReadAsString(pos - GetReadPos() + 1); // 这里的大小是换行之前字符串的长度，+1是为了将 \n 也算上
    }
    std::string GetLineAndPop() /*在这里有可能缓冲区内有数据，但没有换行符，导致卡死在这里*/
    {                           /*是否可以在这里定义一个缓冲区，先将剩下的当做一行存起来。。但如何分辨它的另一半数据呢？？？*/
        std::string str = GetLine();
        MoveReadOffset(str.size());
        return str;
    }
    void clear() /*清理空间【读写偏移量 置 0 即可】*/
    {
        _reader_idx = _writer_idx = 0;
    }
    ~Buffer()
    {
    }
};

#define MAX_LISTEN 1024

class Socket
{
private:
    int _sockfd;
    uint16_t _port;

public:
    Socket() : _sockfd(-1) {}
    Socket(int fd) : _sockfd(fd) {}
    int GetFd() { return _sockfd; }
    bool Sock()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /*协议类型 TCP     #include <netinet/in.h>*/
        if (_sockfd < 0)
        {
            ERROR_LOG("Create socket failed!");
            return false;
        }
        return true;
    }
    bool Bind(const std::string &ip, uint16_t port)
    {
        struct sockaddr_in local
        {
            0
        }; /*使用c++特性 对结构体初始化*/
        local.sin_family = AF_INET;
        local.sin_port = htons(port);
        local.sin_addr.s_addr = inet_addr(ip.c_str());
        socklen_t len = sizeof(local);
        if (bind(_sockfd, (const sockaddr *)&local, len) < 0)
        {
            ERROR_LOG("Bind socket error: fd = %d", _sockfd);
            return false;
        }
        return true;
    }
    bool Listen(int backlog = MAX_LISTEN)
    {
        if (listen(_sockfd, MAX_LISTEN) < 0) /*MAX_LISTEN: 限制同一时间的最大连接数*/
        {
            ERROR_LOG("Listen socket error");
            return false;
        }
        return true;
    }
    bool Connect(const std::string &ip, uint16_t port)
    {
        struct sockaddr_in local
        {
            0
        }; /*使用c++特性 对结构体初始化*/
        local.sin_family = AF_INET;
        local.sin_port = htons(port);
        local.sin_addr.s_addr = inet_addr(ip.c_str());
        socklen_t len = sizeof(local);
        if (connect(_sockfd, (const sockaddr *)&local, len) < 0)
        {
            ERROR_LOG("Connect socket error: fd = %d", _sockfd);
            return false;
        }
        return true;
    }
    int Accept()
    {
        int newfd = accept(_sockfd, nullptr, nullptr);
        if (newfd < 0)
        {
            ERROR_LOG("Accept return newfd error!");
            return -1;
        }
        std::cout << "accept a new fd, is: " << newfd << std::endl;
        return newfd;
    }

    ssize_t Recv(void *buffer, size_t len, int flag = 0)
    {                                                   /*从套接字缓冲区内 读取长度len数据，到buffer内*/
        ssize_t ret = recv(_sockfd, buffer, len, flag); /* <0 出错;  =0连接断开; >0返回读取到的字节数*/
        if (ret <= 0)
        {
            if (errno == EAGAIN || errno == EINTR)
            {             /*EAGAIN表示当前socket的接收缓冲区没有数据了，在非阻塞情况下才会有这个错误*/
                return 0; // 表示暂无数据           /*#EINTR表示socket正在阻塞等待资源时，被信号打断*/
            }
            ERROR_LOG("Recv socket error!");
            return -1;
        }
        return ret;
    }
    ssize_t NoBlockRecv(void *buffer, size_t len)
    {
        if (len == 0)
            return 0;
        return Recv(buffer, len, MSG_DONTWAIT); /*也就是将Recv重新调用一次，传入非阻塞MSG_DONTWAIT参数*/
    }
    ssize_t Send(const void *buffer, size_t len, int flag = 0)
    { /*从buffer中，向套接字缓冲区内，写入len个字节数据*/
        ssize_t ret = send(_sockfd, buffer, len, flag);
        if (ret < 0)
        {
            if (errno == EAGAIN || errno == EINTR)
                return 0;
            ERROR_LOG("Send socket error");
            return -1;
        }
        return ret; /*这里ret指的是，可能socket缓冲区内剩余空间不足，只能写入一部分*/
    }
    ssize_t NoBlockSend(void *buffer, size_t len)
    {
        return Send(buffer, len, MSG_DONTWAIT); /*也就是将Send重新调用一次，传入非阻塞MSG_DONTWAIT参数*/
    }
    void Close()
    {
        if (_sockfd != -1)
        {
            close(_sockfd);
            _sockfd = -1;
        }
    }

    /*服务端必须要绑定一个确定的端口号，以便所有客户端知晓； */
    bool CreateServer(uint16_t port, const std::string &ip = "0.0.0.0", bool flag = false)
    {
        if (Sock() == false)
            return false;
        // int flags = fcntl(_sockfd, F_GETFL, 0);
        // std::cout << "New connection is " << ((flags & O_NONBLOCK) ? "NON-BLOCKING" : "BLOCKING") << std::endl;
        if (flag)
            NonBlock();
        if (Bind(ip, port) == false)
            return false;
        if (Listen() == false)
            return false;
        SetReuseAddress();
        return true;
    }
    bool CreateClient(uint16_t port, const std::string &ip)
    {
        if (Sock() == false)
            return false;
        if (Connect(ip, port) == false)
            return false;
        return true;
    }
    void SetReuseAddress()
    { /*开启地址、端口重用功能  TIME_WAIT*/
        // int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
        int val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));

        val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&val, sizeof(int));
    }
    void NonBlock()
    { /* 对套接字设置非阻塞选项 */
        // int fcntl(int fd, int cmd, ... /* arg */ );
        int flag = fcntl(_sockfd, F_GETFL, 0);
        fcntl(_sockfd, F_SETFL, flag | O_NONBLOCK);
    }
    ~Socket()
    {
        Close();
    }
};

class Poller; // 类的声明
class EventLoop;
class Channel
{
private:
    int _fd; // 对于事件的监控管理，本质是对描述符的监控管理
    EventLoop *_loop;
    uint32_t _events;  // 需要监控的事件
    uint32_t _revents; // 当前连接已触发的事件

    using EventCallBack = std::function<void()>;
    EventCallBack _read_callback;      // 可读事件 触发的回调函数
    EventCallBack _write_callback;     // 可写事件 触发的回调函数
    EventCallBack _error_callback;     // 错误事件 触发的回调函数
    EventCallBack _close_callback;     // 关闭事件 触发的回调函数
    EventCallBack _any_event_callback; // 任意事件 触发的回调函数

public:
    Channel(EventLoop *loop, int fd) : _fd(fd), _events(0), _revents(0), _loop(loop)
    {
    }
    int GetFd() { return _fd; }
    uint32_t GetEvents() { return _events; }
    /*根据uint32_t event判断对什么事件，再通过成员函数判断是否就绪，在执行对应的回调函数*/
    void HandlerEvent()
    {
        if (_revents & EPOLLIN || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI)) // 读事件就绪 或 对方关闭了连接 或 优先数据
        {
            if (_read_callback)
                _read_callback();
        }
        if (_revents & EPOLLOUT) // 读的过程连接可能会断开, 一次处理一个事件
        {
            // 不管接收到什么资源就绪,都需要调用[任意事件就绪回调函数]
            if (_any_event_callback)
                _any_event_callback();
            if (_write_callback)
                _write_callback();
        }
        else if (_revents & EPOLLERR)
        {
            // 不管接收到什么资源就绪,都需要调用[任意事件就绪回调函数] 注意顺序
            if (_any_event_callback)
                _any_event_callback();
            if (_error_callback)
                _error_callback();
        }
        else if (_revents & EPOLLHUP)
        {
            // 不管接收到什么资源就绪,都需要调用[任意事件就绪回调函数]
            if (_any_event_callback)
                _any_event_callback();
            if (_close_callback)
                _close_callback();
        }
        // 不管接收到什么资源就绪,都需要调用[任意事件就绪回调函数] 作用是刷新活跃度
        if (_any_event_callback)
            _any_event_callback(); // 这里要注意 任意事件回调需要在读写上面,因为读写可能会导致执行其他回调函数
    }
    void SetRevents(uint32_t events)
    {
        // 实际某些事件就绪后, EventLoop会向本函数发送已经就绪的events.
        _revents = events;
    }
    void SetReadableCallback(const EventCallBack &cb) // 设置可读事件触发后 执行的回调函数
    {
        _read_callback = cb;
    }
    void SetWriteableCallback(const EventCallBack &cb) // 设置可写事件触发后 执行的回调函数
    {
        _write_callback = cb;
    }
    void SetErrorCallback(const EventCallBack &cb) // 设置错误事件触发后 执行的回调函数
    {
        _error_callback = cb;
    }
    void SetCloseCallback(const EventCallBack &cb) // 设置关闭事件触发后 执行的回调函数
    {
        _close_callback = cb;
    }
    void SetAnyEventCallback(const EventCallBack &cb) // 设置任意事件触发后 执行的回调函数
    {
        _any_event_callback = cb;
    }

    bool Readable() // 当前是否监控可读事件？
    {
        return (_events & EPOLLIN);
    }
    bool Writeable() // 当前是否监控可写事件？
    {
        return (_events & EPOLLOUT);
    }

    /*
        启动读事件监控, 实际上这里添加至_events后，
        还要通过POLL类来调用真正的epoll_wait等函数，达到真正在内核中等待的作用
    */
    void Update();
    void EnableRead()
    {
        _events |= EPOLLIN;
        Update();
    }
    void EnableWrite() // 启动写事件监控
    {
        _events |= EPOLLOUT;
        Update();
    }
    void DisableRead() // 关闭读事件监控
    {
        _events &= ~EPOLLIN; // 0001  ~ 1110 再 &的话, _events中,1的位置不变 0的位置取反
        Update();
    }
    void DisableWrite() // 关闭写事件监控
    {
        _events &= ~EPOLLOUT;
        Update();
    }

    void DisableAll() // 关闭所有事件监控
    {
        _events = 0;
        Update();
    }
    void Remove(); /*移除事件监控，这里不等同于关闭监控，而是将已挂载到内核红黑树中的节点移除*/
};

#define MAX_EPOLL_EVENTS 1024
class Poller
{
private:
    int _epoll_fd;
    struct epoll_event _evs[MAX_EPOLL_EVENTS]; // 时间数组
    std::unordered_map<int, Channel *> _channels;

private:
    void Update(Channel *channel, int opt) // 实际操作,由 UpdateEvent,RemoveEvent 调用
    {
        // int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
        struct epoll_event ev;
        ev.data.fd = channel->GetFd();
        ev.events = channel->GetEvents(); // 获取到想要被监控的事件
        int ret = epoll_ctl(_epoll_fd, opt, channel->GetFd(), &ev);
        if (ret < 0)
        {
            ERROR_LOG("epoll_ctl error");
            abort(); // 退出程序
        }
        return;
    }
    bool HashChannel(Channel *channel) // 判断一个事件是否已经添加进了监控
    {
        auto it = _channels.find(channel->GetFd());
        if (it != _channels.end())
        {
            return true;
        }
        return false;
    }

public:
    Poller() : _epoll_fd(epoll_create(1))
    {
        if (_epoll_fd < 0)
        {
            ERROR_LOG("EPOLL CREATE FAILED");
            abort();
        }
    }
    void UpdateEvent(Channel *channel) // 添加 \ 修改 事件; 要获取事件信息,本质还是需要操作Channel对象.
    {
        if (HashChannel(channel) == false)
        {
            // 添加
            _channels.insert(std::make_pair(channel->GetFd(), channel));
            Update(channel, EPOLL_CTL_ADD);
        }
        Update(channel, EPOLL_CTL_MOD); // 修改 也就是更新s
        return;
    }
    void RemoveEvent(Channel *channel)
    {
        if (HashChannel(channel))
        {
            _channels.erase(channel->GetFd());
            Update(channel, EPOLL_CTL_DEL);
        }
    }
    void Poll(std::vector<Channel *> *active) // 开始监控, 这个vector是一个输出型参数,因为它要返回活跃的事件信息
    {
        // int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
        int nfds = epoll_wait(_epoll_fd, _evs, MAX_EPOLL_EVENTS, 1);
        if (nfds < 0)
        {
            if (nfds == EINTR)
                return; // 信号打断
            ERROR_LOG("EPOLL WAIT ERROR:%s", strerror(errno));
            abort();
        }

        for (int i = 0; i < nfds; i++)
        {
            auto it = _channels.find(_evs[i].data.fd); // 先看能不能在红黑树中找到这个事件,确认这个是有的
            assert(it != _channels.end());
            it->second->SetRevents(_evs[i].events); // 将该描述符下等待的事件 返回给channel
            active->push_back(it->second);
        }
    }
};

/*
    定时任务的设计
*/
#include <iostream>
#include <stdint.h>
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
#include <unordered_map>

using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;

class TimerTask
{
private:
    uint64_t _id;      // 定时器任务的唯一表示符
    uint32_t _timeout; // 定时器任务的超时时间

    TaskFunc _task_cb;    // 定时器任务对象需要执行的任务
    ReleaseFunc _release; // 删除TimeWheel中的对象信息
    bool _canceled;       // false 表示没有被取消，true表示被取消了
public:
    TimerTask(uint64_t id, uint32_t time, const TaskFunc &cb)
        : _id(id), _timeout(time), _task_cb(cb), _canceled(false)
    {
    }
    ~TimerTask()
    {
        // 在这里执行cb
        if (_canceled == false)
        {
            _task_cb();
        }
        _release();
    }
    void SetRelease(const ReleaseFunc &cb)
    {
        _release = cb;
    }
    uint32_t DelayTime()
    {
        return _timeout;
    }
    void Cancel()
    {
        _canceled = true;
    }
};

/*
    时间轮设计
*/
class TimerWheel
{
private:
    using PtrTask = std::shared_ptr<TimerTask>;
    using WeakTask = std::weak_ptr<TimerTask>; // 使用weakptr对于原始TimeTask任务进行管理
    int _tick;
    int _capacity;
    std::vector<std::vector<PtrTask>> _wheel;
    std::unordered_map<uint64_t, WeakTask> _timers;

    EventLoop *_loop;
    int _timerfd; // 定时器描述符 【】
    std::unique_ptr<Channel> _timer_channel;

private:
    void RemoveTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it != _timers.end())
            _timers.erase(id);
    }
    static int CreateTimerfd()
    {
        int timer_fd = timerfd_create(CLOCK_MONOTONIC, 0); // 0默认阻塞操作
        if (timer_fd < 0)
        {
            ERROR_LOG("CREATE TIMERFD ERROR");
            abort();
        }
        struct itimerspec itime;
        itime.it_value.tv_sec = 1;    // 设置为 1 秒
        itime.it_value.tv_nsec = 0;   // 纳秒
        itime.it_interval.tv_sec = 1; // 超时 1 秒后，每次的超时时间
        itime.it_interval.tv_nsec = 0;
        return timer_fd;
    }
    int ReadTimerfd()
    {
        uint64_t times; // 超时多少次, 因为定时器在每次超时后，都会在fd中写入一个8字节的计数
        int ret = read(_timerfd, &times, 8);
        if (ret < 0)
        {
            ERROR_LOG("READ ERROR");
            abort();
        }

        return ret;
    }
    // 每秒被执行一次， 秒针
    void RunTimerTask()
    {
        _tick = (_tick + 1) % _capacity;
        _wheel[_tick].clear(); // 每走一步，将这一步内的TimeTask清空
    }
    void OnTime()
    {
        ReadTimerfd();
        RunTimerTask();
    }
    void TimerAddLoop(uint64_t id, uint32_t time, const TaskFunc &cb)
    {
        PtrTask pt(new TimerTask(id, time, cb)); // 注意用法
        pt->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, id));
        /*
            这里不能直接传入RemoverTimer函数，因为这个函数是在类中的，传过去需要知道是哪个对象要执行该函数
            所以为了区分对象，需要传入this指针，并且bind同时也传入了id。
            同时不能设置为RemoveTimer(this, id)，因为SetRelease需要的是一个可被调用的对象
        */
        _wheel[(_tick + time) % _capacity].push_back(pt);
        _timers[id] = WeakTask(pt);
        /*如果用Shared_ptr来保存的话，就会导致在时间轮内的TimeTask中的计数器永远无法减到 0*/
    }
    void TimerReflashLoop(uint64_t id)
    {
        /*通过保存的weak_ptr 找到需要延时的任务，再创建一个shared_ptr使得计数器 +1，定时时间刷新一次 */
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return; // 没找到 也就没必要刷新
        }
        PtrTask pt = it->second.lock(); // lock获取weakptr管理的shred ptr
        int delay = pt->DelayTime();
        _wheel[(_tick + delay) % _capacity].push_back(pt);
    }
    void TimerCancelLoop(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it != _timers.end())
        {
            PtrTask pt = it->second.lock();
            if (pt)
                pt->Cancel();
        }
    }

public:
    TimerWheel(EventLoop *loop)
        : _capacity(60), _tick(0), _wheel(_capacity), _loop(loop), _timerfd(CreateTimerfd()), _timer_channel(new Channel(_loop, _timerfd))
    {
        _timer_channel->SetReadableCallback(std::bind(&TimerWheel::OnTime, this));
        _timer_channel->EnableRead();
    }

    // 线程安全   转为串行运行
    void TimerADD(uint64_t id, uint32_t time, const TaskFunc &cb);
    void TimerRefresh(uint64_t id);
    void TimerCancel(uint64_t id);
    // 该接口存在线程安全问题
    bool HasTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return false;
        }
        return true;
    }
};

class EventLoop /*主从模型中的 ‘从’，与线程高度相关*/
{
private:
    int _event_fd;                           // 用于环形任务队列的eventfd
    std::unique_ptr<Channel> _event_channel; // 通过channel来管理event_fd
    Poller _poller;                          // 进行对所有描述符的事件监控
    using Functor = std::function<void()>;
    std::vector<Functor> _tasks;
    std::mutex _mutex;
    std::thread::id _thread_id;

    TimerWheel _timer_wheel; // 定时器
public:
    void RunAllTask()
    {
        // 会被多个线程访问到，所以需要加锁
        std::vector<Functor> functor;
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.swap(functor); // ?
        }
        for (auto &f : functor)
        {
            f();
        }
    }
    static int CreateEventFd()
    {
        int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        if (efd < 0)
        {
            ERROR_LOG("Eventfd create error");
            abort();
        }
        return efd;
    }
    void ReadEventfd()
    {
        uint64_t res = 0;
        int ret = read(_event_fd, &res, sizeof(res));
        if (ret < 0)
        {
            if (ret == EINTR || ret == EAGAIN)
            { /*EINTR 被其他信号打断， EAGAIN 无数据可读*/
                return;
            }
            ERROR_LOG("Read eventfd error");
            abort();
        }
        return;
    }
    void WeakUpEventFd()
    {
        uint64_t val = 1;
        int ret = write(_event_fd, &val, sizeof(val));
        if (ret < 0)
        {
            if (ret == EINTR)
            {
                return;
            }
            ERROR_LOG("Write eventfd error");
            abort();
        }
    }

public:
    EventLoop()
        : _thread_id(std::this_thread::get_id()), _event_fd(CreateEventFd()), _event_channel(new Channel(this, _event_fd)), _timer_wheel(this)
    {
        // 给eventfd添加可读事件回调函数，读取eventfd事件通知次数
        _event_channel->SetReadableCallback(std::bind(&EventLoop::ReadEventfd, this));
        // 启动eventfd读事件监控
        _event_channel->EnableRead();
    }

    void Start() // 启动EventLoop模块（事件监控》就绪事件处理》执行任务）
    {
        while (1)
        {
            std::vector<Channel *> actives; // 1. 活跃事件监控
            _poller.Poll(&actives);

            for (auto &f : actives)
            {
                f->HandlerEvent(); // 2. 进行就绪事件对应的回调进行处理
            }

            RunAllTask(); // 3. 执行
        }
    }
    void RunInLoop(const Functor &cb) // 提供一个任务，判断是否在本线程中，决定是否压入队列
    {
        if (isInLoop())
            return cb();
        return QueueInLoop(cb); // 不是一个线程，压入
    }
    void QueueInLoop(const Functor &cb) // 将任务入队列
    {
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.push_back(cb);
        } // 只有出一个作用域 lock才会自动解锁
        // 压入 直接唤醒 执行任务
        WeakUpEventFd(); // 给eventfd写入一个数据，就会唤醒
    }
    bool isInLoop() // 判断当前执行线程是否是eventLoop的线程
    {
        return _thread_id == std::this_thread::get_id();
    }
    void AssertInLoop()
    {
        assert(_thread_id == std::this_thread::get_id());
    }
    void UpdateEvent(Channel *channel) // 添加或修改监控事件，对Poller的二次封装
    {
        return _poller.UpdateEvent(channel);
    }
    void RemoveEvent(Channel *channel) // 移除对描述符的监控
    {
        return _poller.RemoveEvent(channel);
    }
    void TimerAdd(uint64_t id, uint32_t time, const TaskFunc &cb)
    {
        return _timer_wheel.TimerADD(id, time, cb);
    }
    void TimerRefresh(uint64_t id)
    {
        return _timer_wheel.TimerRefresh(id);
    }
    void TimerCancel(uint64_t id)
    {
        return _timer_wheel.TimerCancel(id);
    }
    bool HasTimer(uint64_t id)
    {
        return _timer_wheel.HasTimer(id);
    }
};

enum class ConnStatu
{
    DISCONNECTED, // 连接关闭
    CONNECTING,   // 连接建立初始，未处理相关回调
    CONNECTED,    // 通信状态
    DISCONNECTING // 待关闭状态
};

class Any
{
private:
    class Holder
    {
    public:
        virtual ~Holder() {}
        virtual const std::type_info &type() = 0;
        virtual Holder *clone() = 0;
    };

    template <typename T>
    class PlaceHolder : public Holder
    {
    public:
        PlaceHolder(const T &val)
            : _val(val)
        {
        }
        virtual const std::type_info &type() /*获取子类对象保存的数据类型*/
        {
            return typeid(T); // #include <typeinfo>
        }
        virtual Holder *clone() /*针对当前对象自身，克隆一个新的子类对象*/
        {
            return new PlaceHolder(_val);
        }

    public:
        T _val;
    };

    Holder *_content; /* Any中 只保存Holder指针*/
public:
    Any() : _content(nullptr) {}

    template <typename T>
    Any(const T &val) /*根据给的数据val类型去构造对象*/
        : _content(new PlaceHolder<T>(val))
    {
    }

    Any(const Any &other) /*若other有内容，那么调用克隆函数返回一个父类指针指向的子类对象*/
        : _content(other._content ? other._content->clone() : nullptr)
    {
    }

    template <typename T>
    Any &operator=(const T &val)
    {
        // if(_content != nullptr)
        //     delete _content;
        // _content = new PlaceHolder(val);
        // return *this;
        Any temp(val);
        std::swap(_content, temp._content);
        return *this;
    }
    Any &operator=(const Any &other)
    {
        if (this != &other)
        {
            Any temp(other);
            std::swap(_content, temp._content);
        }
        return *this;
    }

    template <typename T>
    T *Get() /*获取 Holder指向的子类对象所保存的数据类型*/
    {
        assert(typeid(T) == _content->type());
        return &((PlaceHolder<T> *)_content)->_val; /*父类指针强转子类指针，获取子类的_val实例，再取地址*/
    }

    ~Any() { delete _content; }
};

class Connection;
using PtrConnection = std::shared_ptr<Connection>;
class Connection : public std::enable_shared_from_this<Connection>
{ /*这里的连接，指的是通信套接字的连接*/
private:
    uint64_t _conn_id; // 连接的唯一id，便于连接查找
    int _sockfd;
    Socket _socket;   // 关联Socket的所有操作
    Channel _channel; // 所有连接的事件管理
    ConnStatu _statu; // 连接状态的管理，标记当前的连接处于何种状态以便安全关闭

    Buffer _in_buffer;  // 输入缓冲区的管理：这里存放的是  从套接字中读取的数据
    Buffer _out_buffer; // 输出缓冲区的管理：这里存放的是 即将写入套接字的数据

    /* 1. 某段发送过来的请求可能一次并没有读取完，需要进行第二次读取，所以需要记录当前的执行信息
       2. 不同协议对数据有不同的处理方式，因此需要使用Any，接收不同格式的数据*/
    Any _context; // 请求接收处理的上下文信息

    /*组件使用者设置这四个回调函数 实现功能*/
    using ConnectedCallBack = std::function<void(const PtrConnection &)>;
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>;
    using CloseCallback = std::function<void(const PtrConnection &)>;
    using AnyEventCallback = std::function<void(const PtrConnection &)>;
    ConnectedCallBack _connected_callback;
    MessageCallback _message_callback;
    CloseCallback _closed_callback;
    AnyEventCallback _any_event_callback;
    /*组件内的连接关闭回调*/
    CloseCallback _server_close_callback;

    bool _enable_inactive_release; // 启动非活跃连接销毁功能
    uint64_t _timerid;             // 定时器

    EventLoop *_loop; // 也就是连接所关联的独自工作线程

private: /*内部实现接口*/
    // 这里是要将用户操作的这些接口，先保证实在各自的套接字连接中【eventLoop线程】的，保证线程安全
    void EstablishedInLoop() // 获取连接后，需要对该连接所作的各种设置（设置回调，事件等）
    {
        assert(_statu == ConnStatu::CONNECTING); // 当前状态一定是处于【连接中】的状态
        _statu = ConnStatu::CONNECTED;
        // 如果直接启动读监控，那么有可能会直接被触发，导致执行回调时，回调还未定义
        _channel.EnableRead();
        if (_connected_callback)
            _connected_callback(shared_from_this());
    }
    void SendInLoop(Buffer &buf)
    {
        // 不是实际发送接口，是发送到了out_buffer输出缓冲区中
        if (_statu == ConnStatu::DISCONNECTED)
            return;
        _out_buffer.WriteBuffeAndPush(buf);
        if (_channel.Writeable() == false)
        {
            _channel.EnableWrite();
        }
    }
    void ReleaseInLoop() // 实际的释放接口
    {
        // 1. 修改连接状态 DISCONNECTED
        _statu = ConnStatu::DISCONNECTED;
        // 2. 移除事件监控
        _channel.Remove();
        // 3. 关闭描述符
        _socket.Close();
        // 4. 如果定时器队列中还有定时销毁任务，则取消任务
        if (_loop->HasTimer(_conn_id))
            CancelInactiveReleaseInLoop();
        // 5. 调用关闭回调函数
        if (_closed_callback)
            _closed_callback(shared_from_this());
        if (_server_close_callback)
            _server_close_callback(shared_from_this());
    }

    void ShutdownInLoop()
    {
        // 不是实际的连接关闭操作，它是判断目前套接字有没有数据需要被处理或者发送
        _statu = ConnStatu::DISCONNECTING; // 半关闭状态，准备处理未处理数据
        if (_in_buffer.ReadableSize() > 0) // 有数据要接收处理，调用用户回调处理
        {
            if (_message_callback)
                _message_callback(shared_from_this(), &_in_buffer);
        }
        if (_out_buffer.ReadableSize() > 0) // 有数据要发送，等待写事件就绪，进行发送
        {
            if (_channel.Writeable() == false)
            {
                _channel.EnableWrite();
            }
        }
        if (_out_buffer.ReadableSize() == 0) // 没有数据发送，可以关闭了
        {
            Release();
        }
    }
    void EnableInactiveReleaseInLoop(int sec)
    {
        // 启动 非活跃连接释放 规则
        // 1. 设置标志
        _enable_inactive_release = true;
        // 2. 添加定时销毁任务，如果当前存在了一个销毁任务，那么就刷新一下，否则直接新增

        if (_loop->HasTimer(_conn_id))
        {
            return _loop->TimerRefresh(_conn_id);
        }
        return _loop->TimerAdd(_conn_id, sec, std::bind(&Connection::Release, this));
    }
    void CancelInactiveReleaseInLoop()
    {
        _enable_inactive_release = false;
        if (_loop->HasTimer(_conn_id))
        {
            _loop->TimerCancel(_conn_id);
        }
    }
    /*切换协议*/
    void UpgradeInLoop(const Any &context, const ConnectedCallBack &conn,
                       const MessageCallback &msg, const CloseCallback &closed,
                       const AnyEventCallback anyevent)
    {
        _context = context;
        _connected_callback = conn;
        _message_callback = msg;
        _closed_callback = closed;
        _any_event_callback = anyevent;
    }

    /*五个事件回调函数*/
    void HandleRead() // 描述符可读事件就绪，，
    {
        // 1.将套接字中的数据读取到缓冲区
        char buffer[65536];
        int ret = _socket.NoBlockRecv(buffer, 65535);
        if (ret < 0)
        {
            // 现在的出错关闭不能直接关闭连接，而是要检查是否具备可关闭属性（还有没有在处理数据？）
            return ShutdownInLoop();
        }
        _in_buffer.WriteAndPush(buffer, ret); /*这里是处理粘包问题，需要保证读到的是一个完整的报文*/
        // 2. 再调用messageCallBack下一步处理
        if (_in_buffer.ReadableSize() > 0)
        {
            // 它主要用于在一个对象的成员函数内部，安全地获取指向自身的 std::shared_ptr
            return _message_callback(shared_from_this(), &_in_buffer);
        }
    }
    void HandleWrite()
    {
        // out 中保存的数据就是套接字需要发送的数据，先暂存再outbuffer中
        int ret = _socket.NoBlockSend(_out_buffer.GetReadPos(), _out_buffer.ReadableSize());
        if (ret < 0)
        {
            // 发送错误，关闭连接
            if (_in_buffer.ReadableSize() > 0)
            {
                // 这里不处理接收缓冲区的内容直接关闭套接字，会导致已接受的内容被丢弃
                return _message_callback(shared_from_this(), &_in_buffer); //? 这里没有读到数据执行该回调是为什么
            }
            return Release(); // 实际的关闭
        }
        _out_buffer.MoveReadOffset(ret);
        if (_out_buffer.ReadableSize() == 0)
        {
            _channel.DisableWrite(); // 已发送完所有套接字内信息，所以需要关闭写监听了
            if (_statu == ConnStatu::DISCONNECTING)
            { // 若是连接待关闭状态，且发送缓冲区无数据
                return Release();
            }
        }
        return;
    }
    void HandleClose()
    {
        // 一旦执行挂断回调函数，说明此时套接字不用工作了
        // 只需要再检查一下有没有需要处理的接收缓冲区内的数据【这是给用户回调的】
        if (_in_buffer.ReadableSize() > 0)
        {
            // 这里不处理接收缓冲区的内容直接关闭套接字，会导致已接受的内容被丢弃
            return _message_callback(shared_from_this(), &_in_buffer); //? 这里没有读到数据执行该回调是为什么
        }
        return Release();
    }
    void HandleError()
    {
        return HandleClose(); // 执行逻辑一样，直接复用
    }
    void HandleAnyEvent()
    {
        if (_enable_inactive_release == true)
        {
            // 1. 刷新定时任务的声明周期
            _loop->TimerRefresh(_conn_id);
        }
        // 2. 调用 用户 的任意事件回调函数
        if (_any_event_callback)
        {
            _any_event_callback(shared_from_this());
        }
    }

public: /*对外(组件使用者)提供接口*/
    Connection(EventLoop *loop, uint64_t conn_id, int sockfd)
        : _conn_id(conn_id), _sockfd(sockfd), _enable_inactive_release(false), _loop(loop), _statu(ConnStatu::CONNECTING), _socket(_sockfd), _channel(loop, _sockfd)
    {
        _channel.SetCloseCallback(std::bind(&Connection::HandleClose, this));
        _channel.SetAnyEventCallback(std::bind(&Connection::HandleAnyEvent, this));
        _channel.SetReadableCallback(std::bind(&Connection::HandleRead, this));
        _channel.SetWriteableCallback(std::bind(&Connection::HandleWrite, this));
        _channel.SetErrorCallback(std::bind(&Connection::HandleError, this));
    }
    ~Connection()
    {
        DEBUG_LOG("RELEASE CONNECTION:%p", this); // 是否正常释放
    }
    int Fd() { return _sockfd; }
    int ConnectID() { return _conn_id; }
    bool Connected() // 是否处于连接完毕状态
    {
        return _statu == ConnStatu::CONNECTED;
    }
    void SetContext(const Any &context) // 设置上下文
    {
        _context = context;
    }
    Any *GetContext() // 获取上下文
    {
        return &_context;
    }

    /*设置对应的事件回调*/
    void SetConnectedCallBack(const ConnectedCallBack &cb) { _connected_callback = cb; }
    void SetMessageCallback(const MessageCallback &cb) { _message_callback = cb; }
    void SetCloseCallback(const CloseCallback &cb) { _closed_callback = cb; }
    void SetAnyEventCallback(const AnyEventCallback &cb) { _any_event_callback = cb; }
    void SetServerCLoseCallback(const CloseCallback &cb) { _server_close_callback = cb; }

    void Established()
    {
        _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop, this));
    }
    void Send(const char *data, size_t len) /*发送数据至发送缓冲区，套接字启动可写事件监控，写事件资源就绪，才会真正写入套接字*/
    {
        // 用户传来的data可能是临时对象，在任务队列中执行到send时，data可能已经被释放了
        // 所以在这里需要创建一个对象 来保存它
        Buffer _buf;
        _buf.WriteAndPush(data, len);
        _loop->RunInLoop(std::bind(&Connection::SendInLoop, this, std::move(_buf)));
    }
    void Shutdown() /*给用户提供的关闭连接接口，实际上是封装了一层检测套接字是否具备关闭状态，并不是直接关闭*/
    {
        _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
    }
    void Release()
    {
        _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
    }
    void EnableInactiveRelease(int sec) /*启动非活动连接的销毁，sec表示多少秒后销毁*/
    {
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
    }
    void CancelInactiveRelease() /* 取消非活动连接的销毁 */
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop, this));
    }

    /*非线程安全函数*/
    void Upgrade(const Any &context, const ConnectedCallBack &conn,
                 const MessageCallback &msg, const CloseCallback &closed,
                 const AnyEventCallback anyevent) /*切换协议*/
    {
        _loop->AssertInLoop(); // 防止收到的报文以非线程安全的旧的协议解析
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this, context, conn, msg, closed, anyevent));
    }
};

class Acceptor
{
private:
    Socket _socket;   /*用来创建监听套接字*/
    EventLoop *_loop; /*用来监听套接字的读事件，并将获取新连接回调设置*/
    Channel _channel; /*对于监听套接字需要监控事件进行管理【实际只有读事件】*/

    using AccepetCallBack = std::function<void(int)>; /*这个回调是在监听套接字获取完新连接后，需要做的事情*/
    AccepetCallBack _accept_callback;

private:
    void HandleRead() // 设置监听套接字读事件就绪的回调函数【获取新连接 and 调用成功后的回调函数】
    {
        DEBUG_LOG("ACCEPTE HANDLE READ");
        int newfd = _socket.Accept();
        if (newfd < 0)
            return;
        if (_accept_callback)
            _accept_callback(newfd); // 调用获取连接成功后的回调函数
    }
    int CreateServer(int port)
    {
        bool ret = _socket.CreateServer(port);
        assert(ret == true);
        return _socket.GetFd();
    }

public:
    Acceptor(EventLoop *loop, int port)
        : _loop(loop), _socket(CreateServer(port)), _channel(loop, _socket.GetFd())
    {
        _channel.SetReadableCallback(std::bind(&Acceptor::HandleRead, this));
        // 启动读监控不能放在构造中，否则会出现回调函数未设置，但已有事件就绪的情况
    }
    void SetAcceptCallBack(const AccepetCallBack &cb) { _accept_callback = cb; }
    void Listen()
    {
        _channel.EnableRead();
    }
};

class LoopTherad
{
private:
    std::thread _therad; /*EventLoop对应的新线程*/
    EventLoop *_loop;    /*在新线程内部，对其进行实例化，保证强关联性*/

    std::mutex _mutex;
    std::condition_variable _cond; // 保证同步关系，防止线程是创建了，但Loop还没有被实例化，在此期间不能获取loop对象
private:
    void TheradEntry() /*每个创建后的线程默认执行的入口函数【1. 实例化EventLoop对象 ，2.运行start】*/
    {
        // 1. 实例化loop对象
        EventLoop loop;

        // 2. 唤醒在等待loop对象的条件变量下等待的线程
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop = &loop;
            _cond.notify_all();
        }
        loop.Start();
    }

public:
    LoopTherad()
        : _loop(nullptr), _therad(std::thread(&LoopTherad::TheradEntry, this))
    {
    }
    EventLoop *GetEventLoop() /*因为这是一次封装类，并且外部想要添加对象等操作就必须要有一个EventLoop类，所以提供一个接口用来获取*/
    {
        EventLoop *retloop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _cond.wait(lock, [&]()
                       { return _loop != nullptr; }); /* 在这个lambda表达式条件变量下等待，为true*/
            retloop = _loop;
        }
        return retloop;
    }
};

class LoopThreadPoll
{
private:
    int _thread_count;
    int _next_idx;
    EventLoop *_baseloop;
    std::vector<LoopTherad *> _threads;
    std::vector<EventLoop *> _loops;

public:
    LoopThreadPoll(EventLoop *baseloop)
        : _thread_count(0), _next_idx(0), _baseloop(baseloop)
    {
    }
    void SetThreadCount(int count)
    {
        _thread_count = count;
    }
    void Create()
    {
        if (_thread_count > 0)
        {
            _threads.resize(_thread_count);
            _loops.resize(_thread_count);
            for (int i = 0; i < _thread_count; i++)
            {
                _threads[i] = new LoopTherad(); /*这里已经创建好了从属线程与Eventloop*/
                _loops[i] = _threads[i]->GetEventLoop();
            }
        }
        return;
    }
    EventLoop *NextWorkLoop()
    {
        if (_thread_count == 0)
        {
            /*因为都是主模型线程来申请的，所以当_thread为0时，直接使用主模型来进行操作即可*/
            return _baseloop;
        }
        _next_idx = (_next_idx + 1) % _thread_count; // 按顺序进行轮转分配从属线程
        return _loops[_next_idx];
    }
};

class TCPServer
{
private:
    uint32_t _port;
    uint64_t _next_id;                                  /*自动增长的通信连接id*/
    EventLoop _baseloop;                                /*主模型的监听管理对象*/
    Acceptor _acceptor;                                 /*监听套接字的管理对象*/
    LoopThreadPoll _pool;                               /*从属线程管理*/
    std::unordered_map<uint64_t, PtrConnection> _conns; /*所有连接的管理*/
    int _timeout;                                       /*非活跃统计时间，超过timeout就执行销毁任务*/
    bool _enable_inactive_release;

    using ConnectedCallBack = std::function<void(const PtrConnection &)>;
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>;
    using CloseCallback = std::function<void(const PtrConnection &)>;
    using AnyEventCallback = std::function<void(const PtrConnection &)>;
    using Functor = std::function<void()>;
    ConnectedCallBack _connected_callback;
    MessageCallback _message_callback;
    CloseCallback _closed_callback;
    AnyEventCallback _any_event_callback;

private:
    /*为一个新连接（通信套接字）创建一个Connnection对象，对需要的事件进行监听，并设置回调*/
    void NewConnection(int fd)
    {
        _next_id++;
        DEBUG_LOG("NEW CONNECTION FUNCTIO");
        PtrConnection conn(new Connection(_pool.NextWorkLoop(), _next_id, fd));
        conn->SetMessageCallback(_message_callback);
        conn->SetCloseCallback(_closed_callback);
        conn->SetConnectedCallBack(_connected_callback);
        conn->SetAnyEventCallback(_any_event_callback);
        conn->SetServerCLoseCallback(std::bind(&TCPServer::RemoveConnection, this, std::placeholders::_1));
        if (_enable_inactive_release == true)
            conn->EnableInactiveRelease(_timeout); // 启动非活跃超时销毁

        conn->Established(); // 就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }

    /*从管理所有连接的_conns中，移除连接信息，因为现在的Connection对象都被shared_ptr所维护
      并且map中存放的是weak_ptr，移除信息必须将map中的ptr进行释放，ptr才会被真正被移除*/
    void RemoveConnectionInLoop(const PtrConnection &conn)
    {
        int id = conn->ConnectID();
        auto it = _conns.begin();
        if (it != _conns.end())
        {
            _conns.erase(id);
        }
    }
    void RemoveConnection(const PtrConnection &conn)
    {
        _baseloop.RunInLoop(std::bind(&TCPServer::RemoveConnectionInLoop, this, conn));
    }

    void RunAfterInLoop(const Functor &task, int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id, delay, task);
    }

public:
    TCPServer(int port)
        : _port(port), _next_id(0), _enable_inactive_release(false), _acceptor(&_baseloop, port), _pool(&_baseloop)
    {
        // ERR :::  _pool.Create();     /*创建一定数量的从属线程池*/ //不能放在构造函数中，此时还未设置大小
        _acceptor.SetAcceptCallBack(std::bind(&TCPServer::NewConnection, this, std::placeholders::_1));
        _acceptor.Listen(); /*监听套接字*/
    }
    void SetThreadCount(int count)
    {
        return _pool.SetThreadCount(count);
    }

    /*设置对应的事件回调*/
    void SetConnectedCallBack(const ConnectedCallBack &cb) { _connected_callback = cb; }
    void SetMessageCallback(const MessageCallback &cb) { _message_callback = cb; }
    void SetCloseCallback(const CloseCallback &cb) { _closed_callback = cb; }
    void SetAnyEventCallback(const AnyEventCallback &cb) { _any_event_callback = cb; }

    void EnableInactiveRelease(int timeout)
    {
        _timeout = timeout;
        _enable_inactive_release = true;
    }
    void RunAfter(const Functor &task, int delay) /*添加一个定时任务，使其在delay秒后被执行*/
    {
        _baseloop.RunInLoop(std::bind(&TCPServer::RunAfterInLoop, this, task, delay));
    }
    void Start()
    {
        _pool.Create();
        return _baseloop.Start();
    }
};

//////////////////////
void Channel::Update() { _loop->UpdateEvent(this); } // channel与poll定义前后问题
void Channel::Remove() { _loop->RemoveEvent(this); }
void TimerWheel::TimerADD(uint64_t id, uint32_t time, const TaskFunc &cb)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerAddLoop, this, id, time, cb));
}

void TimerWheel::TimerRefresh(uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerReflashLoop, this, id));
}

void TimerWheel::TimerCancel(uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelLoop, this, id));
}

class NetWork
{
public:
    NetWork()
    {
        DEBUG_LOG("SIGPIPE INIT");
        signal(SIGPIPE, SIG_IGN);
    }
};
static NetWork network;